package application;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.awt.CardLayout;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import application.Node;
import application.graph.GraphGenerator;
import application.presenter.GraphWindow;
import application.presenter.VisualGraph;

/**
 * @author Krystian
 * @author siwy
 */

public class Window extends javax.swing.JFrame {

	private static final long serialVersionUID = 1534731679235922850L;

	private final static Logger log = Logger.getLogger(Window.class.getName());
	private final static String cardFromFileDescription = "z pliku";
	private final static String cardGenerateDescription = "generowanie losowych wartości";
	private JFileChooser fc;
	private final static String defaultColors = "kolory domyślne";
	private File fileGraph = null;
	private File fileColors = null; // jak null będzie cały czas to trzeba
									// losować kolory
	private File fileOutput = null;
	private boolean inputFromFile = true;
	private int verticesNumber;
	private int edgesNumber;
	private int colorsNumber;
	private int colorsMinValueForVertex;
	private int colorsMaxValueForVertex;
	private ArrayList<Integer> colorsUser = new ArrayList<Integer>(); // lista
																		// kolorów
																		// zdefiniowanych
																		// przez
																		// usera
	private Node[] graph;

	/**
	 * Creates new form NewJFrame
	 */
	public Window() {
		setTitle("List coloring");
		initComponents();
		fc = new JFileChooser();
		insertDefaultValues();

	}

	/**
	 * wprowadzienie domyślnych wartości dla przyśpieszenia testów
	 */
	private void insertDefaultValues() {
		// fileOutput = new File("C:/Users/Krystian/Desktop/graph2.txt");
		fileOutput = new File("/home/siwy/Pulpit/graf/wyniki");
		fIleGraphOutput.setText(fileOutput.getAbsolutePath());
		fileGraph = new File("/home/siwy/Pulpit/graf/graf2");
		// fileGraph = new File("C:/Users/Krystian/Desktop/graph.txt");
		fIleGraphInput.setText(fileGraph.getAbsolutePath());
	}

	/**
	 * Pobranie wartości z formularza bądz pliku, ich walidacja oraz
	 * wyświetlenie ewentualnych błędów
	 * 
	 * @return czy wartości są poprawne
	 */
	@SuppressWarnings("resource")
	private boolean getAndValidateValues() {
		boolean isOk = true;
		String message = "";
		if (inputFromFile) {
			if (fileGraph == null) {
				message += "Nie podano pliku z danymi grafu \n";
				isOk = false;
			} else {
				try {
					// odczytywanie grafu
					LineNumberReader lineReader = new LineNumberReader(
							new FileReader(fileGraph));
					int lines = 0;
					String line;

					try {
						while ((line = lineReader.readLine()) != null) {
							lines++;
							log.info("aktualna linia: " + line);
							String[] lineItems = line.split("\\|");
							log.info("ilość lineItems: " + lineItems.length);
							if (lineItems.length != 3) {
								isOk = false;
								message = "Nieprawidłowa ilość '|' w lini numer "
										+ lines;
								break;
							}
						}

					} catch (IOException ex) {
						Logger.getLogger(Window.class.getName()).log(
								Level.SEVERE, null, ex);
					}
					log.info("linii w pliku: " + lines);
					graph = new Node[lines + 1];

					// robimy tablicę indeksowaną od 1 żeby się potem gdzieś nie
					// pomylić

					if (isOk) {
						lineReader = new LineNumberReader(new FileReader(
								fileGraph));
						log.info("aktualna linia: "
								+ lineReader.getLineNumber());
						try {
							int currentLine = 0;

							while ((line = lineReader.readLine()) != null) {
								currentLine++;
								log.info("linia pliku z grafu: " + line);

								String[] lineItems = line.split("\\|");

								// for (int i=0;i<lineItems.length;i++){
								// log.info("lineitem["+i+"]: "+lineItems[i]);
								// }
								// indeks wierzchołka:
								Scanner scanner = new Scanner(lineItems[0]);

								int nodeIndex;
								if (scanner.hasNextInt()) {
									nodeIndex = scanner.nextInt();
									log.info("wcztano indeks wierzchołka");
									if (nodeIndex != currentLine) {
										isOk = false;
										message += "Błędny numer wierzchołka w pliku grafu w linii numer: "
												+ currentLine + "\n";
									}
								} else {
									message += "Niezdefiniowany numer wierzchołka w pliku grafu w linii numer: "
											+ currentLine + "\n";
									nodeIndex = currentLine;
								}
								graph[currentLine] = new Node();
								log.info("nowy wierzchołek dla indeksu: "
										+ currentLine);
								// wierzchołki sąsiadujące:
								scanner = new Scanner(lineItems[1]);
								while (scanner.hasNextInt()) {
									int adjacentNodeIndex = scanner.nextInt();
									if (adjacentNodeIndex > (graph.length - 1)
											|| adjacentNodeIndex < 1) {
										isOk = false;
										message += "Błędny numer sąsiadującego wierzchołka: "
												+ adjacentNodeIndex
												+ " w pliku grafu dla wierzchołka "
												+ nodeIndex + "\n";
									} else if (adjacentNodeIndex == nodeIndex) {
										isOk = false;
										message += "Wierzchołek " + nodeIndex
												+ " sąsiaduje sam ze sobą\n";
									} else if (graph[currentLine]
											.hasAdjacentNode(adjacentNodeIndex)) {
										isOk = false;
										message += "Lista sąsiedztwa wierzchołka "
												+ nodeIndex
												+ " zawiera nadmiarową deklarację wierzchołka "
												+ adjacentNodeIndex + "\n";

									} else {
										graph[currentLine]
												.insertAdjacentNode(adjacentNodeIndex);
									}
								}

								// kolory:
								scanner = new Scanner(lineItems[2]);
								boolean colorsDefinied = false;
								while (scanner.hasNextInt()) {
									graph[currentLine].insertColor(scanner
											.nextInt());
									colorsDefinied = true;
								}

								if (!colorsDefinied) {
									isOk = false;
									message += "Dla wierzchołka numer "
											+ nodeIndex
											+ " nie zdefiniowano żadnych kolorów\n";
								}

								scanner.close();
								// sortujemy
								Collections.sort(graph[currentLine]
										.getAdjacentNodes());
								Collections.sort(graph[currentLine]
										.getPossibleColors());
							}

							for (int i = 1; i < graph.length; i++) {
								log.info("sprawdzam sąsiedztow dla wierzchołka "
										+ i);
								Node node = graph[i];

								for (int adjacentNode : node.getAdjacentNodes()) {
									log.info("spradzam sąsiedztwo"
											+ adjacentNode);
									if (!graph[adjacentNode].hasAdjacentNode(i)) {
										isOk = false;
										message += "Wierzchołek "
												+ i
												+ " zawiera w liście sąsiedztwa wierzchołek "
												+ adjacentNode
												+ " a w liście sąsiedztwa dla wierzchołka "
												+ adjacentNode
												+ " nie jest zawarty wierzchołek "
												+ i + "\n";
									}
								}
							}

						} catch (IOException ex) {
							Logger.getLogger(Window.class.getName()).log(
									Level.SEVERE, null, ex);
						}

						try {
							lineReader.close();
						} catch (IOException ex) {
							Logger.getLogger(Window.class.getName()).log(
									Level.SEVERE, null, ex);
						}
					}
				} catch (FileNotFoundException ex) {
					log.log(Level.SEVERE, null, ex);
				}

			}

			// odczytywanie kolorów:
			if (fileColors != null) {
				try {
					Scanner fileScanner = new Scanner(fileColors);
					while (fileScanner.hasNextInt()) {
						int color = fileScanner.nextInt();
						colorsUser.add(color);
						log.info("dodano kolor: " + color);

					}
					fileScanner.close();

				} catch (FileNotFoundException ex) {
					log.log(Level.SEVERE, null, ex);
				}
			}

		} else {
			verticesNumber = Integer.parseInt(tVertices.getText());
			edgesNumber = Integer.parseInt(tEdges.getText());
			colorsNumber = Integer.parseInt(tColorNumber.getText());
			colorsMinValueForVertex = Integer
					.parseInt(tColorRangeMin.getText());
			colorsMaxValueForVertex = Integer
					.parseInt(tColorRangeMax.getText());

			if (verticesNumber < 1) {
				message += "Podano niewłaściwą liczbę wierzchołków \n";
				isOk = false;
			}

			if (edgesNumber < 0
					|| edgesNumber > ((verticesNumber * (verticesNumber - 1)) / 2)) {
				message += "Podano niewłaściwą liczbę krawędzi \n";
				isOk = false;
			}

			if (colorsNumber < 1) {
				message += "Podano niewłaściwą liczbę kolorów \n";
				isOk = false;
			} else if (colorsMinValueForVertex < 0
					|| colorsMaxValueForVertex < 1
					|| colorsMaxValueForVertex > colorsNumber
					|| colorsMinValueForVertex > colorsMaxValueForVertex) {
				message += "Podano niewłaściwy zakres kolorów \n";
				isOk = false;
			}

		}

		if (fileOutput == null) {
			message = message + "Nie podano pliku wyjściowego \n";
			isOk = false;
		}

		if (!isOk) {
			JOptionPane.showMessageDialog(getContentPane(),
					"Wprowadzone dane są błędne: \n\n" + message,
					"Niewłaściwe dane", JOptionPane.ERROR_MESSAGE);
		}
		log.log(Level.INFO, "walidacja:" + Boolean.toString(isOk));
		return isOk;
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 * 
	 * Okno stworzone w Netbeansie
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		graphView = new javax.swing.JPanel();
		jPanel6 = new javax.swing.JPanel();
		jPanel1 = new javax.swing.JPanel();
		jLabel1 = new javax.swing.JLabel();
		ComboInputChooser = new javax.swing.JComboBox();
		startButton = new javax.swing.JButton();
		startButton1 = new javax.swing.JButton();
		jPanel4 = new javax.swing.JPanel();
		jLabel8 = new javax.swing.JLabel();
		fIleGraphOutput = new javax.swing.JTextField();
		jButton4 = new javax.swing.JButton();
		cardsInput = new javax.swing.JPanel();
		cardFromFile = new javax.swing.JPanel();
		jLabel2 = new javax.swing.JLabel();
		jLabel3 = new javax.swing.JLabel();
		fIleGraphInput = new javax.swing.JTextField();
		fileInputColors = new javax.swing.JTextField();
		jButton1 = new javax.swing.JButton();
		jButton2 = new javax.swing.JButton();
		jButton5 = new javax.swing.JButton();
		cardGenerate = new javax.swing.JPanel();
		jLabel10 = new javax.swing.JLabel();
		jLabel16 = new javax.swing.JLabel();
		jLabel17 = new javax.swing.JLabel();
		jLabel18 = new javax.swing.JLabel();
		tVertices = new javax.swing.JFormattedTextField();
		tColorRangeMax = new javax.swing.JFormattedTextField();
		tEdges = new javax.swing.JFormattedTextField();
		tColorNumber = new javax.swing.JFormattedTextField();
		tColorRangeMin = new javax.swing.JFormattedTextField();
		jLabel4 = new javax.swing.JLabel();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setName("contentFrame"); // NOI18N

		javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(
				graphView);
		graphView.setLayout(jPanel5Layout);
		jPanel5Layout.setHorizontalGroup(jPanel5Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 916,
				Short.MAX_VALUE));
		jPanel5Layout.setVerticalGroup(jPanel5Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 352,
				Short.MAX_VALUE));

		getContentPane().add(graphView, java.awt.BorderLayout.CENTER);

		jLabel1.setText("Metoda wprowadzania danych:");

		ComboInputChooser
				.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
						cardFromFileDescription, cardGenerateDescription }));
		ComboInputChooser.addItemListener(new java.awt.event.ItemListener() {
			public void itemStateChanged(java.awt.event.ItemEvent evt) {
				ComboInputChooserItemStateChanged(evt);
			}
		});
		ComboInputChooser
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						ComboInputChooserActionPerformed(evt);
					}
				});

		startButton.setText("Start");
		startButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				startButtonActionPerformed(evt);
			}
		});

		startButton1.setText("Pomoc");
		startButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				startButton1ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(
				jPanel1);
		jPanel1.setLayout(jPanel1Layout);
		jPanel1Layout
				.setHorizontalGroup(jPanel1Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel1Layout
										.createSequentialGroup()
										.addComponent(
												jLabel1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												229,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												ComboInputChooser,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												317,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap(40, 40, 40)
										.addComponent(
												startButton,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												100,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												startButton1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												100,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap(0, 0, Short.MAX_VALUE)));
		jPanel1Layout
				.setVerticalGroup(jPanel1Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel1Layout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												jPanel1Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(
																jLabel1,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																32,
																Short.MAX_VALUE)
														.addComponent(
																ComboInputChooser,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																startButton)
														.addComponent(
																startButton1))));

		jLabel8.setText("Plik z wynikami:");

		fIleGraphOutput.setCursor(new java.awt.Cursor(
				java.awt.Cursor.TEXT_CURSOR));
		fIleGraphOutput.setDisabledTextColor(new java.awt.Color(0, 0, 0));
		fIleGraphOutput.setEnabled(false);

		jButton4.setText("Wybierz plik");
		jButton4.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton4ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(
				jPanel4);
		jPanel4.setLayout(jPanel4Layout);
		jPanel4Layout
				.setHorizontalGroup(jPanel4Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel4Layout
										.createSequentialGroup()
										.addComponent(jLabel8)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												fIleGraphOutput,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												455,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap(18, 18, 18)
										.addComponent(jButton4)
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));
		jPanel4Layout
				.setVerticalGroup(jPanel4Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel4Layout
										.createSequentialGroup()
										.addGap(14, 14, 14)
										.addGroup(
												jPanel4Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel8)
														.addComponent(
																fIleGraphOutput,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(jButton4))
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		cardsInput.setLayout(new java.awt.CardLayout());

		jLabel2.setText("Plik grafu:");

		jLabel3.setText("Plik kolorów:");

		fIleGraphInput.setDisabledTextColor(new java.awt.Color(0, 0, 0));
		fIleGraphInput.setEnabled(false);

		fileInputColors.setText(defaultColors);
		fileInputColors.setDisabledTextColor(new java.awt.Color(0, 0, 0));
		fileInputColors.setEnabled(false);
		fileInputColors.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				fileInputColorsActionPerformed(evt);
			}
		});

		jButton1.setText("Wybierz plik");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setText("Wybierz plik");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

		jButton5.setText("Kolory domyślne");
		jButton5.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton5ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout cardFromFileLayout = new javax.swing.GroupLayout(
				cardFromFile);
		cardFromFile.setLayout(cardFromFileLayout);
		cardFromFileLayout
				.setHorizontalGroup(cardFromFileLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								cardFromFileLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												cardFromFileLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING,
																false)
														.addGroup(
																cardFromFileLayout
																		.createSequentialGroup()
																		.addComponent(
																				jLabel2)
																		.addGap(37,
																				37,
																				37)
																		.addComponent(
																				fIleGraphInput,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				456,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(18,
																				18,
																				18)
																		.addComponent(
																				jButton1,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				Short.MAX_VALUE))
														.addGroup(
																cardFromFileLayout
																		.createSequentialGroup()
																		.addComponent(
																				jLabel3)
																		.addGap(18,
																				18,
																				18)
																		.addComponent(
																				fileInputColors,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				456,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(18,
																				18,
																				18)
																		.addComponent(
																				jButton2)))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(jButton5)
										.addContainerGap(74, Short.MAX_VALUE)));
		cardFromFileLayout
				.setVerticalGroup(cardFromFileLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								cardFromFileLayout
										.createSequentialGroup()
										.addGap(16, 16, 16)
										.addGroup(
												cardFromFileLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel2)
														.addComponent(
																fIleGraphInput,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(jButton1))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)
										.addGroup(
												cardFromFileLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel3)
														.addComponent(
																fileInputColors,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(jButton2)
														.addComponent(jButton5))
										.addGap(46, 46, 46)));

		cardsInput.add(cardFromFile, "cardFromFile");

		jLabel10.setText("Liczba wierzchołków:");

		jLabel16.setText("Liczba krawędzi:");

		jLabel17.setText("Zakres kolorów dla wierzchołka:");

		jLabel18.setText("Liczba kolorów:");

		tVertices
				.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
						new javax.swing.text.NumberFormatter(
								new java.text.DecimalFormat("#0"))));
		tVertices.setText("20");

		tColorRangeMax
				.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
						new javax.swing.text.NumberFormatter(
								new java.text.DecimalFormat("#0"))));
		tColorRangeMax.setText("4");

		tEdges.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
				new javax.swing.text.NumberFormatter(
						new java.text.DecimalFormat("#0"))));
		tEdges.setText("15");

		tColorNumber
				.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
						new javax.swing.text.NumberFormatter(
								new java.text.DecimalFormat("#0"))));
		tColorNumber.setText("5");

		tColorRangeMin
				.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
						new javax.swing.text.NumberFormatter(
								new java.text.DecimalFormat("#0"))));
		tColorRangeMin.setText("2");

		jLabel4.setText(" –");
		jLabel4.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

		javax.swing.GroupLayout cardGenerateLayout = new javax.swing.GroupLayout(
				cardGenerate);
		cardGenerate.setLayout(cardGenerateLayout);
		cardGenerateLayout
				.setHorizontalGroup(cardGenerateLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								cardGenerateLayout
										.createSequentialGroup()
										.addGap(28, 28, 28)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addComponent(jLabel17)
														.addComponent(jLabel10))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING,
																false)
														.addGroup(
																cardGenerateLayout
																		.createSequentialGroup()
																		.addComponent(
																				tColorRangeMin,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				50,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(1,
																				1,
																				1)
																		.addComponent(
																				jLabel4,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				18,
																				javax.swing.GroupLayout.PREFERRED_SIZE)
																		.addGap(2,
																				2,
																				2)
																		.addComponent(
																				tColorRangeMax,
																				javax.swing.GroupLayout.PREFERRED_SIZE,
																				50,
																				javax.swing.GroupLayout.PREFERRED_SIZE))
														.addComponent(tVertices))
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED,
												149, Short.MAX_VALUE)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addComponent(jLabel16)
														.addComponent(jLabel18))
										.addGap(18, 18, 18)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING,
																false)
														.addComponent(
																tEdges,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																100,
																Short.MAX_VALUE)
														.addComponent(
																tColorNumber))
										.addContainerGap(129, Short.MAX_VALUE)));
		cardGenerateLayout
				.setVerticalGroup(cardGenerateLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								cardGenerateLayout
										.createSequentialGroup()
										.addGap(12, 12, 12)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel10)
														.addComponent(jLabel16)
														.addComponent(
																tVertices,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																tEdges,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addGap(18, 18, 18)
										.addGroup(
												cardGenerateLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel17)
														.addComponent(jLabel18)
														.addComponent(
																tColorNumber,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																tColorRangeMin,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																tColorRangeMax,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE)
														.addComponent(
																jLabel4,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																13,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addContainerGap(
												javax.swing.GroupLayout.DEFAULT_SIZE,
												Short.MAX_VALUE)));

		cardsInput.add(cardGenerate, "cardGenerate");

		javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(
				jPanel6);
		jPanel6.setLayout(jPanel6Layout);
		jPanel6Layout
				.setHorizontalGroup(jPanel6Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel6Layout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												jPanel6Layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																cardsInput,
																javax.swing.GroupLayout.Alignment.TRAILING,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE)
														.addComponent(
																jPanel4,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE)
														.addComponent(
																jPanel1,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																Short.MAX_VALUE))));
		jPanel6Layout
				.setVerticalGroup(jPanel6Layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								jPanel6Layout
										.createSequentialGroup()
										.addContainerGap()
										.addComponent(
												jPanel1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												cardsInput,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												95,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(
												jPanel4,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												javax.swing.GroupLayout.DEFAULT_SIZE,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addContainerGap(45, Short.MAX_VALUE)));

		getContentPane().add(jPanel6, java.awt.BorderLayout.NORTH);

		pack();
	}// </editor-fold>

	/**
	 * wybór pliku z kolorami
	 * 
	 * @param evt
	 */
	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
		int returnVal = fc.showOpenDialog(getContentPane());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			// This is where a real application would open the file.
			log.log(Level.INFO, "Plik: " + file.getAbsolutePath());
			fileInputColors.setText(file.getAbsolutePath());
			fileColors = file;
		} else {
			log.info("Open command cancelled by user.");

		}
	}

	private void ComboInputChooserActionPerformed(java.awt.event.ActionEvent evt) {

	}

	private void fileInputColorsActionPerformed(java.awt.event.ActionEvent evt) {

	}

	/**
	 * zmiana wartości comboboxa
	 * 
	 * @param evt
	 */
	private void ComboInputChooserItemStateChanged(java.awt.event.ItemEvent evt) {
		CardLayout cl = (CardLayout) (cardsInput.getLayout());
		// cl.show(cardsInput, (String) evt.getItem());
		if (((String) evt.getItem()).equals(cardFromFileDescription)) {
			cl.first(cardsInput);
			inputFromFile = true;
		} else {
			cl.last(cardsInput);
			inputFromFile = false;
		}

		log.info((String) evt.getItem());
	}

	/**
	 * wybór pliku z grafem
	 * 
	 * @param evt
	 */
	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		int returnVal = fc.showOpenDialog(getContentPane());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			// This is where a real application would open the file.
			log.log(Level.INFO, "Plik: " + file.getAbsolutePath());
			fIleGraphInput.setText(file.getAbsolutePath());
			fileGraph = file;
		} else {
			log.info("Open command cancelled by user.");
		}
	}

	/**
	 * wybór pliku wynikowego
	 * 
	 * @param evt
	 */
	private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
		int returnVal = fc.showSaveDialog(getContentPane());
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			// This is where a real application would open the file.
			log.log(Level.INFO, "Plik: " + file.getAbsolutePath());
			fIleGraphOutput.setText(file.getAbsolutePath());
			fileOutput = file;

		} else {
			log.info("Save command cancelled by user.");
		}
	}

	/**
	 * ustawienie domyślnych kolorów
	 * 
	 * @param evt
	 */
	private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {
		fileInputColors.setText(defaultColors);
		fileColors = null;
	}

	/**
	 * funkcja wywoływana po klinięciu przycisku start, wystartowanie algorytmu
	 * 
	 * @param evt
	 */
	private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
		if (getAndValidateValues()) {

			if (!inputFromFile) {
				try {
					// graph=new Node[verticesNumber+1];
					graph = GraphGenerator.generate(verticesNumber,
							edgesNumber, colorsNumber, colorsMinValueForVertex,
							colorsMaxValueForVertex);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			for (int i = 1; i < graph.length; i++) {

				log.info("Wierzchołek " + i + ": " + graph[i].toString());

			}

			Algorithm algorithm = new Algorithm(graph);
			long startTime = System.currentTimeMillis();
			algorithm.doAlgorithm();
			long endTime = System.currentTimeMillis();
			long totalTime = endTime - startTime;
			System.out.println("Czas wykonania algorytmu dla "
					+ (graph.length - 1) + " wierzchołków wynosi " + totalTime
					+ "ms");
			algorithm.saveResultsToFile(fileOutput);
			if (algorithm.wasAlgorithmSuccessful()) {
				String message = "Wierzchołki pokolorowane zostały przy użyciu "
						+ algorithm.getUsedColorNumber() + " kolorów";
				JOptionPane.showMessageDialog(getContentPane(), message,
						"Wynik", JOptionPane.INFORMATION_MESSAGE);

				if (graph.length <= 200) {
					if (fileColors == null) {
						@SuppressWarnings("unused")
						GraphWindow gWindow = new GraphWindow(new VisualGraph(
								graph, algorithm.getColorsOfNodesNormalized(),
								algorithm.getAllNodePossibleColorsNormalized(),
								null));
					} else {
						@SuppressWarnings("unused")
						GraphWindow gWindow = new GraphWindow(new VisualGraph(
								graph, algorithm.getColorsOfNodesNormalized(),
								algorithm.getAllNodePossibleColorsNormalized(),
								fileColors.getAbsolutePath()));
					}
				} else {
					JOptionPane
							.showMessageDialog(
									getContentPane(),
									"Graf wizualny prezentowany jest tylko do 200 wierzcholkow",
									"Komunikat", JOptionPane.ERROR_MESSAGE);
				}

				// if (userDefiniedColors) { // używamy kolorów usera z
				// colorsUser
				// int[] colorOfNodes = algorithm.getColorsOfNodes();
				// for (int i = 1; i < colorOfNodes.length; i++) {
				// log.info(i + " : " + colorOfNodes[i]);
				// // iterujemy po wierzchołkach i drukujemy int
				// // odpowiadający kolorowi
				// }
				// } else { // sami generujemy kolory
				//
				// }

			} else {
				String message = "Nie udało się pokolorować wierzchołków przy użyciu zdefiniowanych kolorów.";
				JOptionPane.showMessageDialog(getContentPane(), message,
						"Wynik", JOptionPane.INFORMATION_MESSAGE);
			}
			// graphView=algorithm.showGraph();
		}
	}

	/**
	 * Wyświetlenie pomocy
	 * 
	 * @param evt
	 */
	private void startButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		String message = "Dane grafu wczytywane z pliku tekstowego muszą być umieszczone w oddzielnych liniach, a każda z nich musi mieć postać: \n";
		message += "v | v1 v2 v3 v4 .. | c0 c1 c2 c3 ..\n";
		message += "gdzie: \nv - indeks wierzchołka, musi on odpowiadać numerowi linii w której się znajduje\n";
		message += "v1 v2 v3 v4 ..  - lista sąsiednich wierzchołków z wierzchołkiem v\n";
		message += "c0 c1 c2 c3 .. - liczby całkowite reprezentujące kolory możliwe do przyjęcia przez wierzchołek\n";
		message += "\nKolory wczytywane z pliku muszą być umieszczone w oddzielnych liniach w postaci: \n";
		message += "660000\n";
		message += "003399\n";
		message += "Kolejne kolory będą odpowiadać kolejnym wartościom całkowitym kolorów z pliku grafu.";
		JOptionPane.showMessageDialog(getContentPane(), message, "Pomoc",
				JOptionPane.INFORMATION_MESSAGE);
	}

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		/* Set the Nimbus look and feel */
		// <editor-fold defaultstate="collapsed"
		// desc=" Look and feel setting code (optional) ">
		/*
		 * If Nimbus (introduced in Java SE 6) is not available, stay with the
		 * default look and feel. For details see
		 * http://download.oracle.com/javase
		 * /tutorial/uiswing/lookandfeel/plaf.html
		 */
		try {
			for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager
					.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					javax.swing.UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(Window.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(Window.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(Window.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(Window.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		}
		// </editor-fold>

		/* Create and display the form */
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new Window().setVisible(true);
			}
		});
	}

	// Variables declaration - do not modify
	@SuppressWarnings("rawtypes")
	private javax.swing.JComboBox ComboInputChooser;
	private javax.swing.JPanel cardFromFile;
	private javax.swing.JPanel cardGenerate;
	private javax.swing.JPanel cardsInput;
	private javax.swing.JTextField fIleGraphInput;
	private javax.swing.JTextField fIleGraphOutput;
	private javax.swing.JTextField fileInputColors;
	private javax.swing.JButton jButton1;
	private javax.swing.JButton jButton2;
	private javax.swing.JButton jButton4;
	private javax.swing.JButton jButton5;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JLabel jLabel10;
	private javax.swing.JLabel jLabel16;
	private javax.swing.JLabel jLabel17;
	private javax.swing.JLabel jLabel18;
	private javax.swing.JLabel jLabel2;
	private javax.swing.JLabel jLabel3;
	private javax.swing.JLabel jLabel4;
	private javax.swing.JLabel jLabel8;
	private javax.swing.JPanel jPanel1;
	private javax.swing.JPanel jPanel4;
	private javax.swing.JPanel graphView;
	private javax.swing.JPanel jPanel6;
	private javax.swing.JButton startButton;
	private javax.swing.JButton startButton1;
	private javax.swing.JFormattedTextField tColorNumber;
	private javax.swing.JFormattedTextField tColorRangeMax;
	private javax.swing.JFormattedTextField tColorRangeMin;
	private javax.swing.JFormattedTextField tEdges;
	private javax.swing.JFormattedTextField tVertices;
	// End of variables declaration
}
